home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / drivers / decX11.c < prev    next >
C/C++ Source or Header  |  1994-04-15  |  12KB  |  581 lines

  1. /*
  2.  * VOGLE driver for X11 under the DEC window manager.
  3.  *
  4.  *    ok so we admit that we don't know heaps about X11, but come
  5.  * on guys, this shouldn't be neccessary (wild comment from DEC about
  6.  * why our standard X11 driver won't work is welcome.)
  7.  */
  8. #include <stdio.h>
  9. #include <X11/Xlib.h>
  10. #include <X11/Xutil.h>
  11.  
  12. #include "vogl.h"
  13.  
  14. #define LARGEX11R2    "courier12f.snf"
  15. #define SMALLX11R2    "courier10f.snf"
  16.  
  17. #define LARGEX11R3    "-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1"
  18. #define SMALLX11R3    "-adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1"
  19.  
  20. #define MIN(x,y)    ((x) < (y) ? (x) : (y))
  21. #define    CMAPSIZE    256
  22. #define    EV_MASK        KeyPressMask|ButtonReleaseMask|ExposureMask|ButtonPressMask
  23.  
  24. static    Window        winder;
  25. static    Display        *display;
  26. static    int        screen;
  27. static    unsigned long    carray[CMAPSIZE];
  28. static    Colormap    colormap;
  29.  
  30. static    Drawable    theDrawable;
  31. static    GC        theGC;
  32. static    Pixmap        bbuf;        /* Back buffer pixmap */
  33. static    int        back_used;    /* Have we backbuffered ? */
  34.  
  35. static    XFontStruct    *font_id;
  36. XEvent            event;
  37.  
  38. static    int        size;
  39. static    unsigned long    colour;
  40. static    unsigned int    h, w;
  41.  
  42. /*
  43.  * DECX11_init
  44.  *
  45.  *    initialises X11 display.
  46.  */
  47. int DECX11_init(void)
  48. {
  49.     int        i;
  50.     int        x, y, prefx, prefy, prefxs, prefys;
  51.     unsigned int    bw, depth, mask;
  52.     Window        rootw, childw, topwinder, *kiddies;
  53.     char        *av[2], name[50];
  54.  
  55.     XSetWindowAttributes    theWindowAttributes;
  56.         XSizeHints              theSizeHints;
  57.         unsigned long           theWindowMask;
  58.     XWMHints                theWMHints;
  59.  
  60.  
  61.     av[0] = "vogl.X11";
  62.     av[1] = (char *)NULL;
  63.  
  64.     if ((display = XOpenDisplay((char *)NULL)) == (Display *)NULL) {
  65.         fprintf(stderr,"vogl: DECX11_init: can't connect to X server\n");
  66.         exit(1);
  67.     }
  68.  
  69.     winder = DefaultRootWindow(display);
  70.     screen = DefaultScreen(display);
  71.     vdevice.depth = DefaultDepth(display, screen);
  72.     colormap = DefaultColormap(display, screen);
  73.  
  74.     /*
  75.      * Set our standard colors...
  76.      */
  77.     if (vdevice.depth == 1) {
  78.         /*
  79.          * Black and white - anything that's not black is white.
  80.          */
  81.         carray[0] = BlackPixel(display, screen);
  82.         for (i = 1; i < CMAPSIZE; i++)
  83.             carray[i] = WhitePixel(display, screen);
  84.     } else {
  85.         /*
  86.          * Color, try to get our colors close to what's in the
  87.          * default colormap.
  88.          */
  89.         DECX11_mapcolor(0, 0, 0, 0);
  90.         DECX11_mapcolor(1, 255, 0, 0);
  91.         DECX11_mapcolor(2, 0, 255, 0);
  92.         DECX11_mapcolor(3, 255, 255, 0);
  93.         DECX11_mapcolor(4, 0, 0, 255);
  94.         DECX11_mapcolor(5, 255, 0, 255);
  95.         DECX11_mapcolor(6, 0, 255, 255);
  96.         DECX11_mapcolor(7, 255, 255, 255);
  97.     }
  98.  
  99.     getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
  100.  
  101.     XQueryPointer(display, winder, &rootw, &childw, &x, &y, &x, &y, &mask);
  102.  
  103.     if (childw == None)
  104.         childw = rootw;
  105.  
  106.     /*
  107.      * there is something very weird about dec's window manager
  108.      * as expressed on a dec station, to get the details for the window
  109.      * we are actually in we have to get the root window of the childw
  110.      * which gives us the root window of the real window stack, and then
  111.      * we use XQueryPointer to find the real child window.
  112.      */
  113.  
  114.     XQueryTree(display, childw, &rootw, &rootw, &kiddies, &i);
  115.  
  116.     topwinder = winder;
  117.     winder = kiddies[0];
  118.     XQueryPointer(display, winder, &rootw, &childw, &x, &y, &x, &y, &mask);
  119.  
  120.     XGetGeometry(display, childw, &rootw, &x, &y, &w, &h, &bw, &depth);
  121.  
  122.     if (prefx > -1) {
  123.             x = prefx;
  124.             y = prefy;
  125.     }
  126.  
  127.     if (prefxs > -1) {
  128.             w = prefxs;
  129.             h = prefys;
  130.     }
  131.  
  132.     x += bw;
  133.     y += bw;
  134.  
  135.     w -= 2 * bw;
  136.     h -= 2 * bw;
  137.  
  138.     theWindowAttributes.override_redirect = False;
  139.  
  140.         /*theWindowMask = CWBackPixel|CWBorderPixel|CWOverrideRedirect;*/
  141.  
  142.         theWindowMask = CWOverrideRedirect;
  143.  
  144.         winder = XCreateWindow(display,
  145.                                 topwinder,
  146.                                 x, y,
  147.                                 w, h,
  148.                                 bw,
  149.                                 (int)depth,
  150.                                 InputOutput,
  151.                                 CopyFromParent,
  152.                                 theWindowMask,
  153.                                 &theWindowAttributes
  154.                         );
  155.  
  156.         theWMHints.initial_state = NormalState;
  157.         theWMHints.flags = StateHint;
  158.         XSetWMHints(display, winder, &theWMHints);
  159.  
  160.         theSizeHints.flags = PPosition|PSize;
  161.         theSizeHints.x = x;
  162.         theSizeHints.y = y;
  163.         theSizeHints.width = w;
  164.         theSizeHints.height = h;
  165.  
  166.         XSetNormalHints(display, winder, &theSizeHints);
  167.  
  168.     sprintf(name, "vogl %d", getpid());
  169.  
  170.     XSetStandardProperties(display,
  171.         winder,
  172.         name,
  173.         name,
  174.         None,
  175.         av,
  176.         1,
  177.         &theSizeHints
  178.     );
  179.  
  180.     XSelectInput(display, winder, EV_MASK);
  181.  
  182.     theDrawable = (Drawable)winder;
  183.  
  184.     /*
  185.      *  Let VOGLE know about the window size.
  186.      */
  187.     vdevice.sizeX = vdevice.sizeY = MIN(h, w) - 1;
  188.     vdevice.sizeSx = w - 1;
  189.     vdevice.sizeSy = h - 1;
  190.  
  191.     /*
  192.      * Create Graphics Context and Drawable
  193.      */
  194.     theGC = XDefaultGC(display, screen);
  195.     theDrawable = (Drawable)winder;
  196.     DECX11_color(0);
  197.  
  198.     XMapRaised(display, winder);
  199.     XFlush(display);
  200.  
  201.     /*
  202.      * Wait for Exposure event.
  203.      */
  204.     do {
  205.         XNextEvent(display, &event);
  206.     } while (event.type != Expose);
  207.  
  208.     if (prefx == -1 && prefxs == -1)
  209.         XSetInputFocus(display, winder, RevertToParent, CurrentTime);
  210.  
  211.     back_used = 0;
  212.  
  213.     return(1);
  214. }
  215.  
  216. /*
  217.  * DECX11_exit
  218.  *
  219.  *    cleans up before returning the window to normal.
  220.  */
  221. int DECX11_exit(void)
  222. {
  223.     XFreeGC(display, theGC);
  224.  
  225.     if (back_used) 
  226.         XFreePixmap(display, bbuf);
  227.  
  228.     XUnmapWindow(display, winder);
  229.  
  230.     XDestroyWindow(display, winder);
  231.  
  232.     return(1);
  233. }
  234.  
  235. /*
  236.  * DECX11_draw
  237.  *
  238.  *    draws a line from the current graphics position to (x, y).
  239.  *
  240.  * Note: (0, 0) is defined as the top left of the window in X (easy
  241.  * to forget).
  242.  */
  243. int DECX11_draw(
  244.   int x,
  245.   int y)
  246. {
  247.     XDrawLine(display,
  248.         theDrawable,
  249.         theGC,
  250.         vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy,
  251.         x, vdevice.sizeSy - y
  252.     );
  253.  
  254.     XFlush(display);
  255. }
  256.  
  257. /*
  258.  * DECX11_getkey
  259.  *
  260.  *    grab a character from the keyboard - blocks until one is there.
  261.  */
  262. int DECX11_getkey(void)
  263. {
  264.     char    c;
  265.  
  266.     do {
  267.         XNextEvent(display, &event);
  268.         if (event.type == KeyPress) {
  269.             if (XLookupString(&event, &c, 1, NULL, NULL) > 0)
  270.                 return((int)c);
  271.             else
  272.                 return(0);
  273.         }
  274.     } while (event.type != KeyPress);
  275. }
  276.  
  277. /*
  278.  * DECX11_checkkey
  279.  *
  280.  *    Check if there has been a keyboard key pressed.
  281.  *    and return it if there is.
  282.  */
  283. int DECX11_checkkey(void)
  284. {
  285.     char    c;
  286.     int    i;
  287.  
  288.     if (!XCheckWindowEvent(display, winder, KeyPressMask, &event))
  289.         return(0);
  290.  
  291.     if (event.type == KeyPress)
  292.         if (XLookupString(&event, &c, 1, NULL, NULL) > 0)
  293.             return((int)c);
  294.  
  295.     return(0);
  296. }
  297.  
  298. /*
  299.  * DECX11_locator
  300.  *
  301.  *    return the window location of the cursor, plus which mouse button,
  302.  * if any, is been pressed.
  303.  */
  304. int DECX11_locator(
  305.   int *wx,
  306.   int *wy)
  307. {
  308.     Window    rootw, childw;
  309.     int    x, y, mask;
  310.  
  311.     XQueryPointer(display, winder, &rootw, &childw, &x, &y, wx, wy, &mask);
  312.  
  313.     *wy = (int)vdevice.sizeSy - *wy;
  314.  
  315.     return(mask >> 8);
  316. }
  317.  
  318. /*
  319.  * DECX11_clear
  320.  *
  321.  * Clear the screen (or current buffer )to current colour
  322.  */
  323. int DECX11_clear(void)
  324. {
  325.     XSetBackground(display, theGC, colour);
  326.     XFillRectangle(display,
  327.         theDrawable,
  328.         theGC,
  329.         vdevice.minVx,
  330.         vdevice.minVy, 
  331.         (unsigned int)vdevice.maxVx,
  332.         (unsigned int)vdevice.maxVy
  333.     );
  334. }
  335.  
  336. /*
  337.  * DECX11_color
  338.  *
  339.  *    set the current drawing color index.
  340.  */
  341. int DECX11_color(int ind)
  342. {
  343.     colour = carray[ind];
  344.     XSetForeground(display, theGC, colour);
  345. }
  346.  
  347. /*
  348.  * DECX11_mapcolor
  349.  *
  350.  *    change index i in the color map to the appropriate r, g, b, value.
  351.  */
  352. int DECX11_mapcolor(
  353.   int i,
  354.   int r,
  355.   int g,
  356.   int b)
  357. {
  358.     int    stat;
  359.     XColor    tmp;
  360.  
  361.     if (i >= CMAPSIZE)
  362.         return(-1);
  363.  
  364.  
  365.     /*
  366.      * For Black and White.
  367.      * If the index is 0 and r,g,b != 0 then we are remapping black.
  368.      * If the index != 0 and r,g,b == 0 then we make it black.
  369.      */
  370.     if (vdevice.depth == 1) {
  371.         if (i == 0 && (r != 0 || g != 0 || b != 0)) 
  372.             carray[i] = WhitePixel(display, screen);
  373.         else if (i != 0 && r == 0 && g == 0 && b == 0)
  374.             carray[i] = BlackPixel(display, screen);
  375.     } else {
  376.         tmp.red = (unsigned short)(r / 255.0 * 65535);
  377.         tmp.green = (unsigned short)(g / 255.0 * 65535);
  378.         tmp.blue = (unsigned short)(b / 255.0 * 65535);
  379.         tmp.flags = 0;
  380.         tmp.pixel = (unsigned long)i;
  381.  
  382.         if ((stat = XAllocColor(display, colormap, &tmp)) =